/*  This file is part of o.O.

    o.O is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    o.O is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with o.O.  If not, see <http://www.gnu.org/licenses/>.

    Copyright 2013 Oliver Katz */

/* HELLO THERE!

If you're trying to use o.O, then this is not the place to look for
documentation! Try in builder.h. */

#ifndef __OO_PARSING_TYPES_H
#define __OO_PARSING_TYPES_H

#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <fstream>
#include <sstream>
#include <streambuf>

#include <unistd.h>

namespace oO
{
	class Page
	{
	private:
		std::string path;
		std::string buf;

	public:
		Page();
		Page(std::string s) : path("--"), buf(s) {}
		Page &read(std::string p);
		std::string &buffer();
		std::string getPath();
		std::string line(unsigned int n);
	};

	class PageLocation
	{
	private:
		unsigned int line;
		unsigned int column;

	public:
		PageLocation();
		PageLocation(int l, int c) : line(l), column(c) {}
		unsigned int getLine();
		unsigned int getColumn();
		std::string displayColor(Page p, std::string c);
		std::string displayMultiline(Page p, std::string s);
	};

	class Token
	{
	private:
		std::string content;
		PageLocation location;

	public:
		Token();
		Token(std::string s) : content(s) {}
		Token(std::string s, PageLocation l) : content(s), location(l) {}
		Token(std::string s, int l, int c) : content(s), location(l, c) {}
		std::string get();
		operator std::string ();
		PageLocation getLocation();
		operator PageLocation ();
	};

	class AST
	{
	public:
		typedef std::vector<AST>::iterator iterator;

	private:
		std::string name;
		std::map<std::string, Token> content;
		std::vector<AST> children;

	public:
		AST();
		AST(std::string n) : name(n) {}
		AST &adopt(AST c);
		AST &operator << (AST c);
		std::string getName();
		Token &operator [] (std::string c);
		iterator begin();
		iterator end();
		bool leaf();
		void dump(std::string pref);
		void dump();
	};

	class Error
	{
	private:
		Page page;
		PageLocation location;
		std::string msg;
		std::vector<std::string> notes;
		std::map<std::string, std::string> svalues;
		std::map<std::string, int> ivalues;

	public:
		Error();
		Error(Page p, PageLocation l, std::string m) : page(p), location(l), msg(m) {}
		Error &note(std::string n);
		Error &value(std::string n, std::string v);
		Error &value(std::string n, int v);
		void dump();
	};

	extern std::vector<Error> errorBuffer;
	void dumpAndDieIfErrors();
}

#endif
